package com.example.demo.stream;

import com.example.demo.mode.Address;
import com.example.demo.mode.User;
import com.example.demo.mode.UserF;
import com.example.demo.mode.UserVo;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @author pengyifeng
 * @version 5.0
 * @ClassName OptionalDemo.java
 * @Description TODO
 * @createTime 2021年05月13日 15:33:00
 */
public class OptionalDemo {

    @Test
    public void d1(){
        //Optional.ofNullable(userVo) 和 Optional.of(userVo) 区别，ofNullable()如果是空对象会返回empty，of()如果是空对象会报NullPointerException
        //不是的，一个东西存在那么自然有存在的价值。当我们在运行过程中，不想隐藏NullPointerException。而是要立即报告，这种情况下就用Of函数。但是不得不承认，这样的场景真的很少。博主也仅在写junit测试用例中用到过此函数。
        UserVo userVo=null;
        System.out.println(Optional.ofNullable(userVo));
        System.out.println(Optional.of(userVo));
    }

    @Test
    public void d2(){
        //这两个函数的区别：当user值不为null时，orElse函数依然会执行createUser()方法，而orElseGet函数并不会执行createUser()方法，大家可自行测试。
        UserVo userVo=null;
        UserVo userVoo=new UserVo();
        userVoo.setName("aaa");
        UserVo userVo1 = Optional.ofNullable(userVo).orElse(createUserVo());
        UserVo userVo2 = Optional.ofNullable(userVo).orElseGet(() -> createUserVo());

        UserVo userVo11 = Optional.ofNullable(userVoo).orElse(createUserVo());
        UserVo userVo22 = Optional.ofNullable(userVoo).orElseGet(() -> createUserVo());
    }

    @Test
    public void d3() throws Exception {
        //至于orElseThrow，就是value值为null时,直接抛一个异常出去，用法如下所示
        User user=null;
        Optional.ofNullable(user).orElseThrow(()->new Exception("用户不存在"));
    }

    @Test
    public void d4(){
        //map(Function<? super T, ? extends U> mapper)和flatMap(Function<? super T, Optional<U>> mapper)
        //这两个函数放在一组记忆，这两个函数做的是转换值的操作。
        UserVo userVo = createUserVo();
        String s = Optional.ofNullable(userVo).map(u -> u.getName()).get();
        System.out.println(s);

        UserF f=new UserF();
        f.setName("xx");

        String s1 = Optional.ofNullable(f).flatMap(u -> u.getName()).get();
        System.out.println(s1);

    }

    @Test
    public void d5(){
        //4、isPresent()和ifPresent(Consumer<? super T> consumer)
        //
        //这两个函数放在一起记忆，isPresent即判断value值是否为空，而ifPresent就是在value值不为空时，做一些操作。这两个函数的源码如下
        UserVo userVo = createUserVo();
        Optional.ofNullable(userVo).ifPresent(u->u.setAge(19));
        System.out.println(userVo);

    }
    @Test
    public void d6(){
        //filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤，如果包含的值满足条件，那么还是返回这个 Optional；否则返回 Optional.empty。
        Optional<UserVo> userVo = Optional.ofNullable(createUserVo()).filter(u -> u.getName().length() < 6);
        System.out.println(userVo);
    }

    @Test
    public void d7() throws Exception {
        //示例1
        //String city = getCity(createUser());
        //System.out.println(city);
        //String cityJdk8 = getCityJdk8(createUser());
        //System.out.println(cityJdk8);
        System.out.println(getCityJdk8Str(createUser()));
    }


    @Test
    public void d8() {
        //示例2
        User user = getUser(createUser());
        User userJdk8 = getUserJdk8(createUser());
    }

    @Test
    public void d9(){
        //num为null赋予0
        Integer num=null;
        System.out.println(Optional.ofNullable(num).orElseGet(()->0));
    }
    @Test
    public void d10(){
        List<User> userList=new ArrayList<>();
        System.out.println(Optional.ofNullable(userList).isPresent());
    }
    @Test
    public void d11(){
        User user = getUserJdk8(createUser());
        Optional.ofNullable(user).orElseGet(()->{
            System.out.println("不为空");
            return null;
        });
        System.out.println("11");
    }
    //例1 以前写法
    public String getCity(User user)  throws Exception{
        if(user!=null){
            if(user.getAddress()!=null){
                Address address = user.getAddress();
                if(address.getCity()!=null){
                    return address.getCity();
                }
            }
        }
        throw new Exception("取值错误");
    }
    //例1jdk8写法
    public String getCityJdk8(User user) throws Exception {
        return Optional.ofNullable(user)
                .map(u->u.getAddress())
                .map(a->a.getCity())
                .orElseThrow(()->new Exception("取值错误"));
    }
    //例1
    public String getCityJdk8Str(User user) throws Exception {
        return Optional.ofNullable(user)
                .map(u->u.getAddress())
                .map(a->a.getCity())
                .orElseGet(()->{
                    return "asd";
                });
    }

    //例2 以前
    public User getUser(User user){
        if(user!=null){
            String name = user.getName();
            if("zhangsan".equals(name)){
                return user;
            }
        }
        user = new User();
        user.setName("zhangsan");
        return user;
    }
    //例2 jdk8
    public User getUserJdk8(User user){
        return Optional.ofNullable(user).filter(u->"zhangsan".equals(u.getName())).orElseGet(()->{
            User user1=new User();
            user1.setName("ppppp");
            return user1;
        });
    }

    public UserVo createUserVo(){
        UserVo userVo=new UserVo();
        userVo.setName("zzzxxxc");
        return userVo;
    }

    public User createUser(){
        User user=new User();
        user.setName("cccccc");
        //Address address=new Address();
        //address.setCity("bj");
        //user.setAddress(address);
        return user;
    }
}
